﻿using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.DatabaseServices;
using System;
using System.Collections.Generic;
using Galaxy.AutoCAD.Geometrys;

namespace Galaxy.AutoCAD.Databases
{
    public enum PolylineDirection
    {
        Clockwise,
        Anticlockwise,
        Collineation
    }
    public static class PolylineTool
    {
        #region 通过二维点集合创建多段（定义为polyline的括展函数）
        public static void CreatePolyline(this Polyline pl, Point2dCollection pt2dCol, double startWidth, double endWidth)
        {
            for (int i = 0; i < pt2dCol.Count; i++)
            {
                pl.AddVertexAt(i, pt2dCol[i], 0.0, startWidth, endWidth);
            }
        }
        #endregion
        #region 根据圆心、半径、起始角度和终止角度创建多段线形式的圆弧
        public static void CreatePolyArc(this Polyline pl, Point2d centerpoint, double radius, double startAngle, double endAngle, double startWidth, double endWidth)
        {
            Point2d pt1 = new Point2d(centerpoint.X + radius * Math.Cos(startAngle), centerpoint.Y + radius * Math.Sin(startAngle));
            Point2d pt2 = new Point2d(centerpoint.X + radius * Math.Cos(endAngle), centerpoint.Y + radius * Math.Sin(endAngle));
            pl.AddVertexAt(0, pt1, Math.Tan((endAngle - startAngle) / 4), startWidth, endWidth);
            pl.AddVertexAt(1, pt2, 0, startWidth, endWidth);
        }
        #endregion
        #region 根据两点创建矩形
        public static void CreateRectangle(this Polyline pl, Point2d pt1, Point2d pt2)
        {
            double minX = Math.Min(pt1.X, pt2.X);
            double maxX = Math.Max(pt1.X, pt2.X);
            double minY = Math.Min(pt1.Y, pt2.Y);
            double maxY = Math.Max(pt1.Y, pt2.Y);
            Point2dCollection pts = new Point2dCollection();
            pts.Add(new Point2d(minX, minY));
            pts.Add(new Point2d(minX, maxY));
            pts.Add(new Point2d(maxX, maxY));
            pts.Add(new Point2d(maxX, minY));
            pl.CreatePolyline(pts, 0, 0);
            pl.Closed = true;
        }
        #endregion
        #region 判断多段线是顺时针还是逆时针
        public static PolylineDirection IsClockwiseOrAnticlockwise(this Polyline pl)
        {
            List<Point3d> pt3ds = new List<Point3d>();
            for (int i = 0; i < pl.NumberOfVertices; i++)
            {
                pt3ds.Add(pl.GetPoint3dAt(i));
            }
            int a;
            Point3d pt3dOfMaxX = Point3dTool.GetPoint3dOfMaximumX(pt3ds, out a);
            if (a == 0)
            {
                Vector2d AB = new Vector2d(pt3ds[0].X - pt3ds[pt3ds.Count - 1].X, pt3ds[0].Y - pt3ds[pt3ds.Count - 1].Y);
                Vector2d BC = new Vector2d(pt3ds[1].X - pt3ds[0].X, pt3ds[1].Y - pt3ds[0].Y);
                double ABXBC = AB.GetVectorProduct(BC);
                if (ABXBC > 0)
                {
                    return PolylineDirection.Clockwise;
                }
                else if (ABXBC < 0)
                {
                    return PolylineDirection.Anticlockwise;
                }
                else
                {
                    return PolylineDirection.Collineation;
                }
            }
            else if (a == pt3ds.Count - 1)
            {
                Vector2d AB = new Vector2d(pt3ds[pt3ds.Count - 1].X - pt3ds[pt3ds.Count - 2].X, pt3ds[pt3ds.Count - 1].Y - pt3ds[pt3ds.Count - 2].Y);
                Vector2d BC = new Vector2d(pt3ds[0].X - pt3ds[pt3ds.Count - 1].X, pt3ds[0].Y - pt3ds[pt3ds.Count - 1].Y);
                double ABXBC = AB.GetVectorProduct(BC);
                if (ABXBC > 0)
                {
                    return PolylineDirection.Clockwise;
                }
                else if (ABXBC < 0)
                {
                    return PolylineDirection.Anticlockwise;
                }
                else
                {
                    return PolylineDirection.Collineation;
                }
            }
            else
            {
                Vector2d AB = new Vector2d(pt3ds[a].X - pt3ds[a-1].X, pt3ds[a].Y - pt3ds[a-1].Y);
                Vector2d BC = new Vector2d(pt3ds[a+1].X - pt3ds[a].X, pt3ds[a+1].Y - pt3ds[a].Y);
                double ABXBC = AB.GetVectorProduct(BC);
                if (ABXBC > 0)
                {
                    return PolylineDirection.Clockwise;
                }
                else if (ABXBC < 0)
                {
                    return PolylineDirection.Anticlockwise;
                }
                else
                {
                    return PolylineDirection.Collineation;
                }
            }
        }
        #endregion
    }
}
